<!DOCTYPE html>
<html lang="en" style="margin: 0">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>item侧拉</title>
    <script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
    <style>
        .item-menu-wrap {
            height: 4rem;
            width: 100%;
            position: relative;

        }

        .item-content {
            height: 4rem;
            display: flex;
            flex-flow: column;
            padding: 0 1rem;
            justify-content: center;
            width: 100%;
            border-bottom: 1px solid #bbbbbb;
        }

        .menu-wrap {
            top: 0;
            left: 100%;
            height: 4rem;
            line-height: 4rem;
            text-align: center;
            color: #ffffff;
            position: absolute;
            width: 100px;
            display: inline-block;
        }

        .menu {
            background-color: coral;
        }

        div, ul, li {
            box-sizing: border-box;
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .basePage {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            overflow-x: hidden;
        }
    </style>
</head>
<body style="margin: 0;height: 100%;width: 100%">
<script type="text/html" id="liItem">

    <li class="item-menu-wrap">
        <div class="item-content">
            <div>我的眼睛用来寻找黎明</div>
            <div>黎明之前必是黑暗</div>
        </div>
        <div class="menu-wrap">
            <div class="menu">删除</div>
        </div>
    </li>

</script>
<div class="basePage">
    <div style="height: 3rem;line-height:3rem;background-color: cornflowerblue; color: white">一些浏览器自带回弹、下拉、上拉导致触发有问题</div>
    <ul id="ul"></ul>
</div>
<script src="Anim.js"></script>
<script>
    $(document).ready(function () {
        for (let i = 0; i < 20; i++) {
            let $temp = $($('#liItem').html());
            $('#ul').append($temp);
        }

        var liEls = document.getElementById('ul').getElementsByTagName('li');

        for (var j = 0; j < liEls.length; j++) {
            let el = liEls[j];
            el.diffX = 0;
            el.onmousedown = function (event) {
                el.diffX = event.clientX - el.offsetLeft;
                el.startX = event.clientX;
                el.startY = event.clientY;

                document.onmousemove = function (event) {
                    var left = event.clientX - el.diffX;

                    var tanX = event.clientX - el.startX;
                    var tanY = event.clientY - el.startY;
                    //限制侧滑生效，防止垂直滚动无效
                    var jiao = Math.abs(Math.atan(tanX / tanY) * 180 / Math.PI);
                    // console.log(jiao);
                    if (jiao > 45) {//会产生问题。当角度不到时，不移动，但鼠标一大段距离后，角度达到，会导致item瞬间出现。
                        console.log('与起始点上Y轴夹角：', jiao);
                        moveFn(left, el)
                    }else{
                        //so 更新坐标和间距
                        el.diffX = event.clientX - el.offsetLeft;
                        el.startX = event.clientX;
                        el.startY = event.clientY;
                    }

                    //阻止事件冒泡-->父元素-->body-->浏览器
                    //防止鼠标滑动搜索
                    event.preventDefault ? event.preventDefault() : (event.returnValue = false)
                }

                document.onmouseup = function (event) {
                    var left = event.clientX - el.diffX;
                    endupFn(left, el);

                    document.onmousemove = null;
                    document.onmouseup = null;
                }
            }

            el.ontouchstart = function (event) {
                el.diffX = event.touches[0].clientX - el.offsetLeft;

                el.startX = event.touches[0].clientX;
                el.startY = event.touches[0].clientY;

                el.ontouchmove = function (event) {
                    var left = event.changedTouches[0].clientX - el.diffX;

                    var tanX = event.changedTouches[0].clientX - el.startX;
                    var tanY = event.changedTouches[0].clientY - el.startY;
                    //限制侧滑生效，防止垂直滚动无效
                    var jiao = Math.abs(Math.atan(tanX / tanY) * 180 / Math.PI);
                    // console.log(jiao);
                    if (jiao > 45) {
                        console.log('与起始点上Y轴夹角：', jiao);
                        moveFn(left, el)
                    }else{
                        el.diffX = event.touches[0].clientX - el.offsetLeft;
                        el.startX = event.touches[0].clientX;
                        el.startY = event.touches[0].clientY;
                    }


                }
                el.ontouchend = function (event) {
                    var left = event.changedTouches[0].clientX - el.diffX;
                    endupFn(left, el)

                    el.touchmove = null;
                    el.touchend = null;
                }
            }

        }


    });

    function moveFn(left, el) {
        var mw = el.getElementsByClassName('menu-wrap')[0].offsetWidth;
        if (-left > mw) {
            left = -mw;
        } else if (left > 0) {
            left = 0;
        }
        el.style.left = left + "px";

    }

    function endupFn(left, el) {

        var mw = el.getElementsByClassName('menu-wrap')[0].offsetWidth;
        if (-left >= mw / 2) {
            openItem(el, mw);
            closeItems(el);
        }
        else if (-left < mw / 2) {
            closeItem(el, mw);
        }
        else if (left > 0) {
            closeItem(el, mw);
        }


    }

    function openItem(el, offL) {
        var anim = new Anim();
        anim.mw = offL;//el.getElementsByClassName('menu-wrap')[0].offsetWidth;
        anim.leftStart = el.offsetLeft;
        anim.leftEnd = -anim.mw;
        anim.isLeft = true;

        var off = (anim.leftEnd - anim.leftStart) / 40;//40帧，每份3毫秒，共120毫秒
        anim.off = off >= 0 ? off : -off;

        anim.changeStyle = function () {

            // console.log(anim.leftStart, anim.leftEnd, anim.off, anim.mw);
            el.style.left = anim.leftStart + 'px';

            if (-anim.leftStart >= anim.mw) {
                el.style.left = -anim.mw + 'px';
                anim.end();
            }
            anim.leftStart = anim.leftStart - anim.off;
        };
        anim.start();

    }

    function closeItem(el, offL) {
        var anim = new Anim();
        anim.mw = offL;//el.getElementsByClassName('menu-wrap')[0].offsetWidth;
        anim.leftStart = el.offsetLeft;
        anim.leftEnd = 0;
        anim.isLeft = false;

        var off = (anim.leftEnd - anim.leftStart) / 40;//40帧，每帧3毫秒，共120毫秒
        anim.off = off >= 0 ? off : -off;

        anim.changeStyle = function () {

            // console.log(anim.leftStart, anim.leftEnd, anim.off, anim.mw);
            el.style.left = anim.leftStart + 'px';

            if (anim.leftStart >= 0) {
                el.style.left = '0px';
                anim.end();
            }
            anim.leftStart = anim.leftStart + anim.off;
        };
        anim.start();

    }

    /***
     * 可在鼠标点击，或手势触摸时调用，并阻止item滑出
     * （当前为：直到第二个item确定滑出，调用）
     * @param item
     */
    function closeItems(item) {

        var liEls = document.getElementById('ul').getElementsByTagName('li');
        for (let i = 0; i < liEls.length; i++) {
            if (liEls[i] !== item && liEls[i].offsetLeft !== 0) {
                closeItem(liEls[i])
            }
        }
    }
</script>
</body>
</html>